/***************************************************************************
 *   Copyright (C) 2009 by Zheng Yonglei
 *   zhengyonglei@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "ReciteWordsWidget.h"

ReciteWordsWidget::ReciteWordsWidget(QWidget *parent)
    : QWidget(parent),
    mAutoSpeak(true)
{
	//cout<<"ReciteWordsWidget::ReciteWordsWidget"<<endl;
	ui.setupUi(this);

	//for importance level
	ui.wordImportanceBox->clear();
	//ui.wordImportanceBox->addItem("1.NOT classified");
	//ui.wordImportanceBox->addItem("2.barely known");
	//ui.wordImportanceBox->addItem("3.capable of spelling");
	//ui.wordImportanceBox->addItem("4.capable of using in writing");
	//ui.wordImportanceBox->addItem("5.very familiar");
	//ui.wordImportanceBox->addItem("6.completely mastered");
	ui.wordImportanceBox->addItem(tr("[1] Unclassified"));
	ui.wordImportanceBox->addItem(tr("[2] Level 1"));
	ui.wordImportanceBox->addItem(tr("[3] Level 2"));
	ui.wordImportanceBox->addItem(tr("[4] Level 3"));
	ui.wordImportanceBox->addItem(tr("[5] Level 4"));
	ui.wordImportanceBox->addItem(tr("[6] Level 5"));

	mDiffLev1 = new QShortcut(QKeySequence(Qt::Key_1),  this);
	mDiffLev2 = new QShortcut(QKeySequence(Qt::Key_2),  this);
	mDiffLev3 = new QShortcut(QKeySequence(Qt::Key_3),  this);
	mDiffLev4 = new QShortcut(QKeySequence(Qt::Key_4),  this);
	mDiffLev5 = new QShortcut(QKeySequence(Qt::Key_5),  this);
	mDiffLev6 = new QShortcut(QKeySequence(Qt::Key_6),  this);

	QObject::connect(mDiffLev1,SIGNAL(activated()),this,SLOT(setImpLev1()));
	QObject::connect(mDiffLev2,SIGNAL(activated()),this,SLOT(setImpLev2()));
	QObject::connect(mDiffLev3,SIGNAL(activated()),this,SLOT(setImpLev3()));
	QObject::connect(mDiffLev4,SIGNAL(activated()),this,SLOT(setImpLev4()));
	QObject::connect(mDiffLev5,SIGNAL(activated()),this,SLOT(setImpLev5()));
	QObject::connect(mDiffLev6,SIGNAL(activated()),this,SLOT(setImpLev6()));
	QObject::connect(ui.wordImportanceBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setWordImpLev(int)));

	//for recite method
	mReciteTest_YesNo = new ReciteTest_YesNo(ui.reciteDisplayArea, this);
	mReciteTest_MultiChoice= new ReciteTest_MultiChoice(ui.reciteDisplayArea, this);
	mReciteTest_Spell = new ReciteTest_Spell(ui.reciteDisplayArea, this);
	testMethod.clear();
	testMethod.push_back(mReciteTest_YesNo);
	testMethod.push_back(mReciteTest_MultiChoice);
	testMethod.push_back(mReciteTest_Spell);

	dynamicButtonGrid = new QGridLayout(ui.reciteMethodButtonArea);
	dynamicButtonGrid->setContentsMargins(0,0,0,0);

	for(int i=0; i<testMethod.size(); i++)
	{
		testMethod[i]->hide();
		dynamicButtonGrid->addWidget(testMethod[i], 1, 1);
		QObject::connect(testMethod[i], SIGNAL(testFinished()), this, SLOT(reciteNextWord()));
		QObject::connect(testMethod[i], SIGNAL(testError_NoWord()), this, SLOT(testError_NoWord()));
		QObject::connect(testMethod[i], SIGNAL(speak()), this, SLOT(speakButtonClicked()));

		//QObject::connect(testMethod[i], SIGNAL(memoryLevelChangedTo(int)), this, SLOT(memoryLevelChangedTo(int)));
		QObject::connect(testMethod[i], SIGNAL(updateMemoryLevel()), this, SLOT(updateMemoryLevel()));
		QObject::connect(testMethod[i], SIGNAL(totalReciteCountChangedTo(int)), this, SLOT(totalReciteCountChangedTo(int)));
		QObject::connect(testMethod[i], SIGNAL(totalFinishedCountChangedTo(int)), this, SLOT(totalFinishedCountChangedTo(int)));
	}

	mEndReciteTaskDialog = new EndReciteTaskDialog();
	mEndReciteTaskDialog->hide();
}

ReciteWordsWidget::~ReciteWordsWidget()
{
	cout<<"ReciteWordsWidget::~ReciteWordsWidget()"<<endl;
}

void ReciteWordsWidget::initReciteTask()
{
	cout<<"ReciteWordsWidget::initReciteTask"<<endl;
	mAutoSpeak=true;
	ui.reciteDisplayArea->reset();
	//cout<<"ReciteWordsWidget::initReciteTask()-->TotalReciteCount="<<WM.getActiveWordTotalReciteCount()<<endl;
	if(WM.reciteNextWord())
	{
		WM.setReviewFrequency();
		float newLevel=WM.getCurWord()->getMemoryLevel();
		if (newLevel>1)
			newLevel=1;

		updateMemoryLevel();
		ui.reciteProgressBar->setMaximum(WM.getActiveWordCount());
		ui.reciteProgressBar->setValue(WM.getActiveWordTotalFinishedCount());
		WM.initActiveWordTotalReciteCount();
		ui.reciteCountLCD->display(WM.getActiveWordTotalReciteCount());
		mReciteTest_YesNo->hide();
		mReciteTest_MultiChoice->hide();
		mReciteTest_Spell->hide();

		beginNewReciteTest();
		emit updateMainBulletin();
	}
	else
		testError_NoWord();
}

void ReciteWordsWidget::updateImportanceLevel()
{
	int importanceLevel = WM.getCurWord()->getImportanceLevel();

	if (importanceLevel > 0 && importanceLevel<6)
	{
		//cout<<"ReciteWordsWidget::updateImportanceLevel = "<<importanceLevel<<endl;
		ui.wordImportanceBox->setCurrentIndex(importanceLevel-1);
	}
	else
	{
		cout<<"ReciteWordsWidget::updateImportanceLevel-->importanceLevel="<<importanceLevel<<endl;
		cout<<"ReciteWordsWidget::updateImportanceLevel-->invalid importanceLevel."<<endl;
		importanceLevel = 3;
		cout<<"ReciteWordsWidget::updateImportanceLevel-->set importanceLevel to 3."<<endl;
		WM.getCurWord()->setImportanceLevel(importanceLevel);
		ui.wordImportanceBox->setCurrentIndex(importanceLevel-1);
		//QCoreApplication::quit();
	}
}

void ReciteWordsWidget::updateMemoryLevel()
{
	//cout<<"ReciteWordsWidget::updateMemoryLevel"<<endl;
	Word* word = WM.getCurWord();
	if (word)
	{
		//float newLevel=WM.getCurWord()->getMemoryLevel();
		QString sheet;
		int progressBarMax=1;
		switch(OPT.curTestMethod)
		{
		case yes_no_method:
			ui.memoryLevelLabel->setText(tr("Yes/No Test"));
			progressBarMax = ReciteTestPolity::getYesNoTestFinishCount(word->getImportanceLevel());
			sheet = mTestProBarStyleSheets[yes_no_method];
			break;
		case multi_exp_choice_method:
			ui.memoryLevelLabel->setText(tr("Multi-Exp Choice Test"));
			progressBarMax = ReciteTestPolity::getMultiExpTestFinishCount(word->getImportanceLevel());
			sheet = mTestProBarStyleSheets[multi_exp_choice_method];
			break;
		case multi_English_choice_method:
			ui.memoryLevelLabel->setText(tr("Multi-Eng Choice Test"));
			progressBarMax = ReciteTestPolity::getMultiEngTestFinishCount(word->getImportanceLevel());
			sheet = mTestProBarStyleSheets[multi_English_choice_method];
			break;
		case spell_method:
			ui.memoryLevelLabel->setText(tr("Spell Test"));
			progressBarMax = ReciteTestPolity::getSpellTestFinishCount(word->getImportanceLevel());
			sheet = mTestProBarStyleSheets[spell_method];
			break;
		default: break;
		}

		//cout<<ui.memoryLevelBar->styleSheet().toUtf8().data()<<endl;
		//ui.memoryLevelBar->setStyleSheet(sheet);
		ui.memoryLevelBar->setMinimum(0);
		ui.memoryLevelBar->setMaximum(progressBarMax);
		ui.memoryLevelBar->setValue(word->getMemoryLevel(OPT.curTestMethod));
	}
	else
	{
		cout<<"ReciteWordsWidget::beginNewReciteTest-->Error! Invalid word."<<endl;
		QCoreApplication::quit();
	}
}

void ReciteWordsWidget::setWordImpLev(int levelArg)
{
	//cout<<"ReciteGREWords::setWordImpLev-->importance = "<<levelArg+1<<endl;
	if (levelArg+1 >= 6)
	{
		cout<<"ReciteWordsWidget::setWordImpLev-->levelArg="<<levelArg<<endl;
		QCoreApplication::quit();
	}

	WM.getCurWord()->setImportanceLevel(levelArg+1);
	ui.wordImportanceBox->setCurrentIndex(levelArg);
}

void ReciteWordsWidget::beginNewReciteTest()
{
	WLOG<<"ReciteWordsWidget::beginNewReciteTest-->mTestMethod = "<<WM.getReciteTestMode()<<endl;
	updateImportanceLevel();
	updateMemoryLevel();

	switch(WM.getReciteTestMode())
	{
	case yes_no_method:
		mReciteTest_YesNo->beginTest();
		break;
	case multi_exp_choice_method:
	case multi_English_choice_method:
		mReciteTest_MultiChoice->beginTest();
		break;
	case spell_method:
		mReciteTest_Spell->beginTest();
		break;
	}
}

bool ReciteWordsWidget::endCurReciteTask()
{
	cout<<"ReciteWordsWidget::endCurReciteTask"<<endl;
	mEndReciteTaskDialog->setFont(this->font());
	switch(mEndReciteTaskDialog->showThisDialog())
	{
	case ST_End:
		emit finishCurTask();
		return true;
		//break;
	case ST_OpenList:
		emit finishCurTask();
		emit openSelectListDialog();
		return true;
		//break;
	case ST_Analyse:
		emit finishCurTask();
		emit openAnalysisDialog();
		return true;
		//break;
	case ST_None:
		this->raise();
		this->activateWindow();
		return false;
		//break;
	default:
		break;//do nothing
	}
}

void ReciteWordsWidget::reciteNextWord()
{
	//cout<<"ReciteWordsWidget::reciteNextWord"<<endl;

	//cout<<"ReciteWordsWidget::reciteNextWord-->WM.getUnhitReviewingWordCount()="<<WM.getUnhitReviewingWordCount()<<endl;
	//cout<<"ReciteWordsWidget::reciteNextWord-->WM.getActiveWordCount()="<<WM.getActiveWordCount()<<endl;
	//cout<<"ReciteWordsWidget::reciteNextWord-->WM.getFinishedWordCount()="<<WM.getFinishedWordCount()<<endl;
	//cout<<"ReciteWordsWidget::reciteNextWord-->WM.getReviewingWordCount()="<<WM.getReviewingWordCount()<<endl;

	WLOG<<endl;
	WLOG<<"<-------------Start a new cycle.------------->"<<endl;
	cout<<"\n<-------------Start a new cycle.------------->"<<endl;

	if(WM.reciteNextWord())
	{
		ui.reciteProgressBar->setMaximum(WM.getActiveWordCount());
		ui.reciteProgressBar->setValue(WM.getActiveWordTotalFinishedCount());
		ui.reciteCountLCD->display(WM.getActiveWordTotalReciteCount());
		emit updateMainBulletin();

		if (	WM.getActiveWordCount() == (WM.getFinishedWordCount() + WM.getReviewingWordCount())
			&& 	WM.getUnhitReviewingWordCount() ==0 )
		{
			if (endCurReciteTask())
					return;
		}
		else
			beginNewReciteTest();
	}
	else
		testError_NoWord();
}

void ReciteWordsWidget::speakButtonClicked()
{
	ui.reciteDisplayArea->speak();
}

void ReciteWordsWidget::testError_NoWord()
{
	QString message="No word to show. You may have finished the current task. Please choose a new one.";
	MessageBox::showWarning(QMessageBox::Warning,QString("Warning!"),message,12,this);
}
